import { CustomRequestOptions, StreamHttpOptions } from '@/interceptors/request'
import { HttpCode } from '@/models/http'
import { LOGIN_PAGE } from '@/models/sys'
import { useUserStore } from '@/store'
import * as TextEncoding from 'text-encoding-shim'
import { processStreamData } from '.'

let isNotLogin = false
export const http = <T>(options: CustomRequestOptions) => {
  // 1. 返回 Promise 对象
  return new Promise<IResData<T>>((resolve, reject) => {
    uni.request({
      ...options,
      dataType: 'json',
      // #ifndef MP-WEIXIN
      responseType: 'json',
      // #endif
      // 响应成功
      success(res: any) {
        if (res.data.status_code === HttpCode.Success) {
          isNotLogin = false
          resolve(res.data as IResData<T>)
        } else if (res.statusCode === HttpCode.NoAuth || res.data.status_code === HttpCode.NoAuth) {
          if (isNotLogin) return
          isNotLogin = true
          uni.showModal({
            title: '重新登陆',
            content: '登录状态已失效，请重新登录',
            showCancel: false,
            success(result) {
              if (result.confirm) {
                uni.hideLoading()
                useUserStore().clearUserInfo()
                uni.reLaunch({ url: LOGIN_PAGE })
                isNotLogin = false
              }
            },
          })
          reject(res)
        } else if (
          res.statusCode === HttpCode.Success &&
          res.data.status_code === HttpCode.Secondary
        ) {
          uni.reLaunch({ url: `${LOGIN_PAGE}?secondary=1` })
          reject(res)
        } else {
          // 其他错误 -> 根据后端错误信息轻提示
          if (!options.hideErrorToast) {
            uni.hideLoading()
            if ((res.data as IResData<T>).message.length > 15) {
              uni.showModal({
                title: '提示',
                content: (res.data as IResData<T>).message,
                showCancel: false,
                success(result) {
                  if (result.confirm) {
                    uni.hideLoading()
                  }
                },
              })
            } else {
              uni.showToast({
                icon: 'none',
                title: (res.data as IResData<T>).message || '请求错误',
              })
            }
          }
          reject(res)
        }
      },
      // 响应失败
      fail(err) {
        uni.showToast({
          icon: 'none',
          title: '网络错误，换个网络试试',
        })
        reject(err)
      },
    })
  })
}

const textEncoding = new TextEncoding.TextDecoder('utf-8')
export const streamHttp = <T>(options: StreamHttpOptions) => {
  const requestTask = uni.request({
    ...options,
    enableChunked: true,
    // responseType: 'arraybuffer',
    // header: {
    //   'Content-Type': 'text/event-stream; charset=utf-8',
    // },
    responseType: 'text',
    // 响应成功
    success(res: any) {
      console.log(res, '------------------success')

      options.onInit?.(res)
    },
    // 响应失败
    fail(err) {
      options.onErr?.(err)
    },
  })
  console.log(requestTask, '------------------requestTask')

  // 在您的代码中使用
  // @ts-ignore
  requestTask.onChunkReceived((res) => {
    const arrayBuffer = res.data
    const uint8Array = new Uint8Array(arrayBuffer)
    const str = textEncoding.decode(uint8Array)

    try {
      if (str.includes('[DONE]')) {
        options.onChange?.(null)
      } else {
        console.log(str)

        const jsonResults = processStreamData(str)

        // 处理每个解析出的JSON对象
        jsonResults.forEach((json) => {
          options.onChange?.(json)
        })
      }
    } catch (error) {
      console.error('处理数据失败:', error)
      console.log(str, '------------------报错')
    }
  })

  return requestTask
}

/**
 * GET 请求
 * @param url 后台地址
 * @param query 请求query参数
 * @returns
 */
export const httpGet = <T>(url: string, query?: Record<string, any>) => {
  return http<T>({
    url,
    query,
    method: 'GET',
  })
}

/**
 * POST 请求
 * @param url 后台地址
 * @param data 请求body参数
 * @param query 请求query参数，post请求也支持query，很多微信接口都需要
 * @returns
 */
export const httpPost = <T>(
  url: string,
  data?: Record<string, any>,
  query?: Record<string, any>,
) => {
  return http<T>({
    url,
    query,
    data,
    method: 'POST',
  })
}

/**
 * POST 请求
 * @param url 后台地址
 * @param data 请求body参数
 * @param query 请求query参数，post请求也支持query，很多微信接口都需要
 * @returns
 */
export const httpSteam = <T>(
  url: string,
  data?: Record<string, any>,
  query?: Record<string, any>,
  onChange?: (res: any) => void,
) => {
  return streamHttp<T>({
    url,
    query,
    data,
    method: 'POST',
    onChange,
  })
}

http.get = httpGet
http.post = httpPost
httpSteam.post = httpSteam
